import { isExistUrl } from '@/utils/router';
import { getToken, setToken } from '@/utils/auth';
import Taro from '@tarojs/taro';
import { toast } from '@/utils';
import { API } from '@/config';

function request<T>(
  url: string,
  method: string,
  data?: any,
  options?: any,
): Promise<T> {
  const parmas = {
    // url: process.env.TARO_APP_API + url, process无法使用，先使用本地地址代替
    url: API() + url,
    method,
    data,
    ...options,
  };
  const token = getToken();
  if (token) parmas.header = { Authorization: token };
  Taro.showLoading();

  return new Promise<T>((resolve, reject) => {
    Taro.request({
      ...parmas,
      success: function (res) {
        const Authorization = res.header['token'] || res.header['Token'];
        console.log(res);
        if (Authorization) setToken(Authorization);
        const { code, msg, data: response } = res.data;
        if (code === 2 || code === 3) {
          toast(msg);
          reject(new Error(msg));
        } else {
          !isExistUrl(url) && toast(msg);
          resolve(response as T);
        }
      },
      fail: reject,
      complete: () => Taro.hideLoading(),
    });
  });
}

// 用于调用 API 的方法，添加泛型参数以支持类型安全
export const get = <T>(url: string, data?: Record<string, any>): Promise<T> => {
  if (data) {
    url = `${url}?${Object.entries(data || {})
      .map(([key, value]) => `${key}=${value}`)
      .join('&')}`;
  }
  return request<T>(url, 'GET');
};

export const post = <T>(
  url: string,
  data?: Record<string, any>,
  flag = false,
  options = {},
): Promise<T> => {
  if (flag) {
    url = `${url}?${Object.entries(data || {})
      .map(([key, value]) => `${key}=${value}`)
      .join('&')}`;
  }
  return request<T>(url, 'POST', data, options);
};

export const put = <T>(
  url: string,
  data?: Record<string, any>,
  options = {},
): Promise<T> => {
  return request<T>(url, 'PUT', data, options);
};

export const del = <T>(
  url: string,
  data?: Record<string, any>,
  options = {},
): Promise<T> => {
  if (data) {
    url = `${url}?${Object.entries(data)
      .map(([key, value]) => `${key}=${value}`)
      .join('&')}`;
  }
  return request<T>(url, 'DELETE', null, options);
};
